#! /bin/bash
#
# postgresql-start
# Set up and run a temporary PostgreSQL instance.
#
# Copyright © 2008–2016 Ben Finney <ben@benfinney.id.au>
# Copyright © 2008–2016 Peter Wright <pete@flooble.net>
# Copyright © 2007–2008 Cybersource Pty. Ltd.
#
# This is free software: see the grant of license at end of this file.

set -o nounset
set -o errexit
set -o errtrace
set -o pipefail

PG_RUN_ROOT=/var/run/postgresqld

# You probably want to bind to somewhere non-default so you
# don't have to shutdown your standard PostgreSQL instance.
BIND_SOCKET="$PG_RUN_ROOT"/postgresqld-ram.sock
BIND_HOST=127.0.0.1
BIND_PORT=5433

# Note that this grabs only the major and minor numbers.
# So if $(psql --version) returns "psql (PostgreSQL) 9.3.5",
# the POSTGRES_VERSION will be "9.3".
POSTGRES_VERSION="$( psql --version | awk '{print $3;}' | cut -d. -f1,2 )"

# We need to run pg_ctl, initdb and postgres.
POSTGRES_BINDIR=/usr/lib/postgresql/"$POSTGRES_VERSION"/bin

# By setting the target to a RAM volume, this can dramatically speed
# up things like running a test suite.
DATA_DIR="/var/lib/postgresql-ram/$POSTGRES_VERSION"
PARENT_DATA_DIR="$(dirname "$DATA_DIR")"

PID_FILE="$PG_RUN_ROOT"/postgresqld-ram.pid
PG_USER=postgres
PG_GROUP=postgres

DB_USER=
DB_PASS=

umask 022
# If not yet done, set up the mount point.
if [ ! -d "$DATA_DIR" ]; then
    printf "Creating directory at ‘%s’: " "$PARENT_DATA_DIR"
    mkdir --parents "$PARENT_DATA_DIR"
    chown $PG_USER:$PG_GROUP "$PARENT_DATA_DIR"
    printf " done.\n"
fi

# We're now going to do stuff we don't want to be persistent,
# so make sure we are going to properly cleanup.
cleanup_exit() {
    # Run without errexit, we want to do as much cleanup
    # as possible.
    set +o errexit

    exit_status=$?
    trap - ERR EXIT SIGTERM SIGHUP SIGINT SIGQUIT

    sudo -u "$PG_USER" "$POSTGRES_BINDIR/pg_ctl" -D "$DATA_DIR" stop

    if mountpoint -q "$PARENT_DATA_DIR" ; then
        printf "Unmounting RAM volume: "
        umount "$PARENT_DATA_DIR"
        printf " done.\n"
    fi

    set -o errexit
    exit $exit_status
}
trap "cleanup_exit" ERR EXIT SIGTERM SIGHUP SIGINT SIGQUIT

if ! mountpoint -q "$PARENT_DATA_DIR" ; then
    printf "Mounting RAM volume at ‘%s’:" "$PARENT_DATA_DIR"
    mount -t tmpfs none "$PARENT_DATA_DIR"
    mkdir "$DATA_DIR"
    chown $PG_USER:$PG_GROUP "$DATA_DIR"
    printf " done.\n"
fi

# Setup the new PostgreSQL data directory.
sudo -u "$PG_USER" "$POSTGRES_BINDIR"/initdb \
     -D "$DATA_DIR"

# Run PostgreSQL in the background.
sudo -u "$PG_USER" "$POSTGRES_BINDIR"/postgres \
     -h $BIND_HOST -p $BIND_PORT \
     -D "$DATA_DIR" &

printf "Giving PostgreSQL a few moments to get started: "
sleep 2
printf " done.\n"

# Optionally create a DB user.
if [ -n "$DB_USER" ]; then
    printf "Creating user ‘%s’ with password ‘%s’: " "$DB_USER" "$DB_PASS"
    sudo -u "$PG_USER" psql \
        -h $BIND_HOST -p $BIND_PORT \
        -c "CREATE USER $DB_USER WITH CREATEDB NOCREATEUSER PASSWORD '$DB_USER'"
    printf " done.\n"
fi

# Wait for the background process to end.
wait


# This is free software: you may copy, modify, and/or distribute this work
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 3 of that license or any later version.
#
# No warranty expressed or implied. See the file ‘LICENSE.GPL-3’ for details,
# or view it online at <URL:https://www.gnu.org/licenses/gpl-3.0.html>.


# Local variables:
# coding: utf-8
# mode: shell-script
# End:
# vim: fileencoding=utf-8 filetype=sh :
